<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>闭包</title>
  <style>
      li {
        line-height: 40px;
      }
      span {
        color: red
      }
    </style>
</head>
<body>
  <h2>闭包: 有权<span>访问</span>另一个函数作用域中变量的<span>函数</span>,返回倒不是必须的</h2>
  <ul>
    <li>
      闭包中虽然在另一个地方被调用了,但是仍然可以访问到函数内部的变量,因为<span>内部函数的作用域链中包含了闭包的作用域</span>
    </li>
    <li>
      即使不出现任何return ,也可以利用全局变量去做一个闭包.也就是说,闭包跟return 语句没有任何关系
    </li>
    <li>
      <h3>执行环境\变量对象\作用域链</h3>
      <ul>
        <li>
          执行环境定义: 变量或者函数有权访问的其他<span>数据</span>(我的理解:执行环境由数据组成,但不是数据,就像社会由人组成,但是它没有两只眼睛两只鼻子)
        </li>
        <li>
          变量对象定义: 每一个执行环境都由与之对应的变量对象<span>由执行环境中所有的变量和函数组成对象</span>然而这个对象是无法通过代码去访问的(相当于存储户口的本子)
        </li>
        <li>特点: 执行环境中的所有代码执行完毕后，该环境就会被销毁，保存在其中的所有变量和函数定义也随之销毁。(人做完一件事可以接着做另一件,当代码做完了该做的所有事情之后,环境跟代码定义的变量一并被销毁了)</li>
        <li>作用域链是由变量对象组成的数据对象链。</li>
        <li>函数中变量对象==活动对象</li>
        <li>
          <span>代码在执行环境中执行时，执行环境会为变量对象创建作用域链,作用域链是由变量对象组成的数据对象链,作用域链的前端，始终是当前函数执行环境的变量对象,作用域链的最后端，始终是全局执行环境的变量对象。</span>
        </li>
      </ul>
    </li>
    <li>
      <h3>闭包在创建和执行的过程</h3>
      <ul>
        <li>1.创建闭包时,创建外部函数与内部函数的变量对象,组成作用域链</li>
        <li>
          2.运行外层函数返回闭包时,<span>复制</span>创建时候的作用域链到执行环境.此时的作用域链为全局-外部-内部的变量对象
        </li>
        <li>
          3.运行完毕后,外层函数的执行环境与作用域链销毁,但是此作用域链仍被闭包引用
        </li>
        <li>
          4.所以存在于内存中的并非时我们之前认为的单个变量而已,<span>存在内存中的,是整个外层函数的变量对象.!!!!!!</span>因为访问了一个变量,所以我们只看到了变量留在了内存中,其实整个变量对象都在
        </li>
        <li>5.想真正的移除这个变量对象,必须将闭包赋值为null,等待垃圾处理机制回收.</li>
      </ul>
    </li>
  </ul>
  <script src="./javascript.js"></script>
</body>
</html>